Promoted attributes are attributes which are displayed prominently in the UI which allow them to be easily viewed and edited.
One way of seeing promoted attributes is as a kind of form with several fields. Each field is just regular attribute, the only difference is that they appear on the note itself.
Attributes can be pretty useful since they allow for querying and script automation etc. but they are also inconveniently hidden. This allows you to select few of the important ones and push them to the front of the user.
In order to have promoted attributes, there needs to be a way to define them.
Technically, attributes are only name-value pairs where both name and value are strings.
The Attribute definition specifies how should this value be interpreted:
To create a new promoted attribute:
When a new promoted attribute definition is created, it creates a corresponding
label prefixed with either label or
relation, depending on the definition type:
#label:myColor(inheritable)="promoted,alias=Color,multi,color"
The only purpose of the attribute definition is to set up a template. If the attribute was marked as promoted, then it's also displayed to the user for easy editing.
|
Notice how the promoted attribute definition only creates a “Due date” box above the text content. |
|
Once a value is set by the user, a new label (or relation, depending on the type) is created. The name of the attribute matches one set when creating the promoted attribute. |
So there's one attribute for value and one for definition. But notice how an definition attribute can be made Inheritable, meaning that it's also applied to all descendant notes. In this case, the definition used for the whole sub-tree while "value" attributes are for each not individually.
It's possible to create promoted attributes out of system attributes, to be able to easily alter them.
Here are a few practical examples:
startDate which
are then interpreted by the calendar view.#shareAlias (see
Sharing) in order to form clean URLs.#color,
simply create a promoted attribute for it to make it easier.Some relations always occur in pairs - my favorite example is on the family.
If you have a note representing husband and note representing wife, then
there might be a relation between those two of isPartnerOf.
This is bidirectional relationship - meaning that if a relation is pointing
from husband to wife then there should be always another relation pointing
from wife to husband.
Another example is with parent-child relationship. Again these always
occur in pairs, but in this case it's not exact same relation - the one
going from parent to child might be called isParentOf and
the other one going from child to parent might be called isChildOf.
Relation definition allows you to specify such "inverse relation" - for
the relation you just define you specify which is the inverse relation.
Note that in the second example we should have two relation definitions
- one for isParentOf which defines isChildOf as
inverse relation and then second relation definition for isChildOf which
defines isParentOf as inverse relation.
What this does internally is that whenever we save a relation which has defined inverse relation, we check that this inverse relation exists on the relation target note. Similarly, when we delete relation, we also delete inverse relation on the target note.